package com.zs.backend.common.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class ExcelParser {

    public static <T> List<T> parseExcelFile(MultipartFile file, Class<T> clazz) {
        List<T> dataList = new ArrayList<>();

        try {
            ExecutorService executorService = Executors.newFixedThreadPool(5); // 创建一个大小为 5 的线程池
            List<List<T>> partialDataLists = new ArrayList<>(); // 存放各个片段的数据列表

            CountDownLatch latch = new CountDownLatch(1); // 用于等待解析完成

            AnalysisEventListener<T> listener = new AnalysisEventListener<T>() {
                private List<T> partialData = new ArrayList<>(); // 临时存放每个片段的数据

                @Override
                public void invoke(T object, AnalysisContext context) {
                    partialData.add(object);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    // 将临时数据列表添加到主数据列表中
                    synchronized (partialDataLists) {
                        partialDataLists.add(new ArrayList<>(partialData));
                    }
                    latch.countDown(); // 解析完成，减少 latch 的计数
                }
            };

            EasyExcel.read(file.getInputStream(), clazz, listener).sheet().doRead();

            // 等待解析完成
            latch.await();

            // 关闭线程池
            executorService.shutdown();
            // 等待所有任务完成
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);

            // 将各个片段的数据合并到一起
            for (List<T> partialData : partialDataLists) {
                dataList.addAll(partialData);
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }

        return dataList;
    }
}
